#include "DescentInject.h"
#include "Helper.h"
#include "Hook.h"
#include <gl/GL.h>

using namespace DescentInject;


//const u32 &playerHealth = *(u32*)0x72D884;
const u16 &playerHealth = *(u16*)0x72D886;

/*
u32 swapEndianness(u32 other)
{
	return ((other & 0xFF000000) >> 24) | ((other & 0xFF0000) >> 8) | ((other & 0xFF00) << 8) | ((other & 0xFF) << 24);
}
*/

void GameTick_Pre STDARG
{
	//log("GameTick_Pre: Player health: %hu", playerHealth);
}

void GameTick_Post STDARG
{
	//log("GameTick_Post");
}

void SwapBuffers_Pre STDARG
{
	//log("SwapBuffers");

	const float maxHalfSize = 0.2f;
	static float halfSize = 0.2f;

	halfSize -= 0.001f;
	if (halfSize < 0) {
		halfSize = maxHalfSize;
	}

	// Because I'm lazy, taken from: http://www.opengl.org/resources/faq/technical/transformations.htm
	glMatrixMode (GL_MODELVIEW);
	glPushMatrix ();
	glLoadIdentity ();
	glMatrixMode (GL_PROJECTION);
	glPushMatrix ();
	glLoadIdentity ();
	glBegin (GL_QUADS);
	glColor3f(0.16f + halfSize, 0.3f - halfSize, 0.5f * halfSize);
	glVertex3f (-halfSize, -halfSize, -1);
	glVertex3f (halfSize, -halfSize, -1);
	glVertex3f (halfSize, halfSize, -1);
	glVertex3f (-halfSize, halfSize, -1);
	glEnd ();
	glPopMatrix ();
	glMatrixMode (GL_MODELVIEW);
	glPopMatrix ();
}

void PlayerDamaged_Pre STDARG
{
	log("Player damaged: ");
	log("Player health: %hu", playerHealth);

	const u32 *t0 = (u32*)Pz[0];
	const u32 *t1 = (u32*)Pz[1];
	const u32 damage = Pz[2] >> 16;		// Some quirky integral format: 0x00040000 = 4

	log("  missile type?: %u", *t0);
	log("  enemy index: %u", *t1);
	log("  damage: %hu", damage);
}

void DescentInject::HookFunctions()
{
	// Main loop
	Hook((PVOID)0x40BA80, GameTick_Pre, GameTick_Post, HOOK_STDCALL, 0);

	// Player took damage
	Hook((PVOID)0x421830, PlayerDamaged_Pre, NULL, HOOK_CDECL, 3);

	// Swap Buffers
	Hook((PVOID)0x4954B0, SwapBuffers_Pre, NULL, HOOK_CDECL, 0);
}

void DescentInject::Initialize()
{
	log("Hooking functions ...");

	HookFunctions();

	log("Done hooking functions");
}
